/*
 * couponDAO.java
 *
 * Created on March 17, 2007, 2:14 PM
 *
 * To change this tcoulate, choose Tools | Tcoulate Manager
 * and open the tcoulate in the editor.
 */

package edu.byu.isys413.mystuff;

import java.util.*;
import java.sql.*;

/**
 *
 * @author Sam Griffiths
 */
public class couponDAO {
    
    //initialize variables
    private static couponDAO instance;
    private String couid;
    private static Cache cache;
    
    /** Creates a new instance of couponDAO */
    public couponDAO() {
    cache = Cache.getInstance();
    }
        
    //returns the current instance of coupon DAO (singleton)
    public static synchronized couponDAO getInstance() {
        if (instance == null) {
            instance = new couponDAO();
            
        }
        return instance;
    }
    
    //creates a new CouponBO initialized with a new ID(guid)
    public couponBO create(){
        couid = Guid.generate();
        couponBO cou = new couponBO(couid);
        cache.put(couid, cou);
        return cou;
    }
    
    /*
     *This method reads all records from the database  and loads a list of Coupon Business objects
     * @parameter : the id of the record
     * @ returns : the customerBO, loaded with the data from the database
     * throws all kinds of exceptions
     */
    public synchronized ArrayList<couponBO> readALL() throws DataException {
        ArrayList<couponBO> coulist = new ArrayList();
        Connection conn = null;
        try {
            //get connection, create a read sql statement, and execute
            conn = ConnectionPool.getInstance().get();
            //System.out.println("Check");
            Statement st = conn.createStatement();
            //System.out.println("Executing Query");
            ResultSet rs = st.executeQuery("SELECT * FROM COUPON_TABLE");
            //System.out.println("Execute Succesful");
            
            //instantiate coupon BO with data from result set
            while(rs.next()){
                couponBO cou = new couponBO(rs.getString("COUPONID"));
                cou.setAmount(Double.valueOf(rs.getString("AMT").trim()).doubleValue());
                cou.setTransactionLineId(rs.getString("TLINEID"));
                cou.setAlreadyInDatabase(true);
                //add to arraylist
                coulist.add(cou);
            }
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return coulist;
    }
    
    //retrieves a conection and hands it to a different read method, returns couponBO, releases connection
    public synchronized couponBO read(String couid) throws DataException{
        couponBO cou = null;
        Connection conn = null;
        try {
            conn = ConnectionPool.getInstance().get();
            //checks cache first to see if already in temporary storage
            if(cache.containsKey(couid))
                cou = (couponBO)cache.get(couid);
            else
                cou = read(conn, couid);
            
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return cou;
    }
    
    //just like readALL, but only pulls out and returns a single instance of a couponBO
    public synchronized couponBO read(Connection conn, String id){
       couponBO cou = null;
        try{
        Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery("SELECT * FROM COUPON_TABLE WHERE COUPONID='"+id+"'");
            cou = new couponBO(id);
            while(rs.next()){
                cou.setAmount(Double.valueOf(rs.getString("SALARY").trim()).doubleValue());
                cou.setTransactionLineId(rs.getString("TLINEID"));
                cou.setAlreadyInDatabase(true);
                            
            }
       }catch(Exception e){}
       //put in cache for later retreival
       cache.put(id, cou);
       return cou;
    }
    ///////////////update//////////////////
    
    /////////////save////////////////////
    public synchronized boolean save(couponBO bo) throws DataException {
       //System.out.println("Save entrance accessed");
        Connection conn = null;
        try {
            //saves only if object is dirty, no changes = no need to save,
            conn = ConnectionPool.getInstance().get();
            if(bo.isDirty())
                save(conn,bo);
            bo.setDirty(false);
            
            ///////////////////////////////////////////
            // call read with a connection (the other read method in this class)
            
            // release the connection
            conn.commit();
            ConnectionPool.getInstance().release(conn);
            
        }catch (ConnectionPoolException e){
            throw new DataException("Could not get a connection to the database.");
            
        }catch (SQLException e) {
            // rollback
            try {
                conn.rollback();
                ConnectionPool.getInstance().release(conn);
            }catch (SQLException e2) {
                throw new DataException("Big error: could not even release the connection", e2);
            }catch (ConnectionPoolException e3){
            }
            
            throw new DataException("Could not retrieve records", e);
        }
        
        return true;
        }
    
    public synchronized void save(Connection conn, couponBO bo){
        //System.out.println("Second Save Accessed");
        try{
            //create statement, check to see if record is already in DB
            Statement st = conn.createStatement();
            String couid = "";
           
            //System.out.println("First Query Skipped");
            if(false == bo.isAlreadyInDatabase()){
                //if not in DB, then INSERT
                String queryString = "INSERT INTO COUPON_TABLE VALUES (?,?,?)";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
               
                //String aString = Double.toString(aDouble);
                pstmt.setString(1,bo.getCouponId());
                pstmt.setString(2,Double.toString(bo.getAmount()));
                pstmt.setString(3,bo.getTransactionLineId());
                pstmt.execute();
                pstmt.close();
                bo.setAlreadyInDatabase(true);
            } else{
                //if in DB update
                String queryString = "UPDATE COUPON_TABLE SET AMT = ?, TLINEID = ?, WHERE COUPONID = ? ";
                PreparedStatement pstmt = conn.prepareStatement(queryString);
                pstmt.setString(1,Double.toString(bo.getAmount()));
                pstmt.setString(2,bo.getTransactionLineId());
                pstmt.setString(3,bo.getCouponId());
                pstmt.execute();
                pstmt.close();
                
            }
        }catch(Exception e){}
    }
    
    /////////////delete////////////////////////
    /*
        We're assuming we will never need to delete a coupon, we want the information permanent to be able to make reports later
     */
    
}
